/* COPYRIGHT_CHUNFENG */
#include <stdio.h>
#include <string.h>
#include "cf_json.h"
#include "cf_string.h"
#include "cf_std.h"
#include "cf_common.h"
#include "lcf_log.h"

CFJsonType CFJsonGetType(CFJson* jObj)
{
    if(!jObj)
        return -1;
    return jObj->type;
}

CFJson* CFJsonNewObject()
{
    return cJSON_CreateObject();
}

CFJson* CFJsonParse(const char* jStr)
{
    if(!jStr)
        return NULL;
    return cJSON_Parse(jStr);
}

int CFJsonPut(CFJson* jObj)
{
    if(!jObj)
        return -1;
    cJSON_Delete(jObj);
    return 0;
}

CFJson* CFJsonNext(CFJson* jObj)
{
    if(!jObj)
        return NULL;
    return jObj->next;
}

CFJson* CFJsonObjectNew()
{
    return cJSON_CreateObject();
}

int CFJsonObjectAdd(CFJson* obj, const char* key, CFJson* objAdd)
{
    if(!obj || !key || !objAdd){
        return -1;
    }
    cJSON_AddItemToObject(obj, key, objAdd);
    return 0;
}

int CFJsonObjectAddInt(CFJson* obj, const char* key, int val)
{
    CFJson* j;
    
    if(!obj || !key)
        return -1;
    if((j=CFJsonIntNew(val))){
        if(CFJsonObjectAdd(obj, key, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1;
}

int CFJsonObjectAddInt64(CFJson* obj, const char* key, long long val)
{
    CFJson* j;
    
    if(!obj || !key)
        return -1;
    if((j=CFJsonInt64New(val))){
        if(CFJsonObjectAdd(obj, key, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1;    
}

int CFJsonObjectAddDouble(CFJson* obj, const char* key, double val)
{
    CFJson* j;
    
    if(!obj || !key)
        return -1;
    if((j=CFJsonDoubleNew(val))){
        if(CFJsonObjectAdd(obj, key, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1; 
}

int CFJsonObjectAddString(CFJson* obj, const char* key, const char* cStr)
{
    CFJson* j;
    
    if(!obj || !key || !cStr)
        return -1;
    if((j=CFJsonStringNew(cStr))){
        if(CFJsonObjectAdd(obj, key, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1;     
}

int CFJsonObjectAddBool(CFJson* obj, const char* key, BOOL val)
{
    CFJson* j;
    
    if(!obj || !key)
        return -1;
    if((j=CFJsonBoolNew(val))){
        if(CFJsonObjectAdd(obj, key, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1; 
}

int CFJsonArrayAddInt(CFJson* obj, int val)
{
    CFJson* j;

    if(!obj)
        return -1;
    if((j=CFJsonIntNew(val))){
        if(CFJsonArrayAdd(obj, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1;  
}

int CFJsonArrayAddInt64(CFJson* obj, long long val)
{
    CFJson* j;
    
    if(!obj)
        return -1;
    if((j=CFJsonInt64New(val))){
        if(CFJsonArrayAdd(obj, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1; 
}

int CFJsonArrayAddDouble(CFJson* obj, double val)
{
    CFJson* j;
    
    if(!obj)
        return -1;
    if((j=CFJsonDoubleNew(val))){
        if(CFJsonArrayAdd(obj, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1; 
}

int CFJsonArrayAddString(CFJson* obj, const char* cStr)
{
    CFJson* j;
    
    if(!obj || !cStr)
        return -1;
    if((j=CFJsonStringNew(cStr))){
        if(CFJsonArrayAdd(obj, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1; 
}

int CFJsonArrayAddBool(CFJson* obj, BOOL val)
{
    CFJson* j;
    
    if(!obj)
        return -1;
    if((j=CFJsonBoolNew(val))){
        if(CFJsonArrayAdd(obj, j)){
            CFJsonPut(j);
            return -1;
        }else{
            return 0;
        }
    }
    return -1; 
}

CFJson* CFJsonObjectGet(CFJson* jObj, const char* key)
{
    if(!jObj)
        return NULL;
    if(jObj->type != cJSON_Object){
        return NULL;
    }
    CFJsonForeach(jObj, tmpObj){
        if(tmpObj->string && !strcmp(tmpObj->string, key)){
            return tmpObj;
        }
    }
    return NULL;
}

CFJson* CFJsonStringNew(const char* cStr)
{
    if(!cStr){
        LCF_ERR("\n");
        return NULL;
    }
    LCF_MSG("\n");
    return cJSON_CreateString(cStr);
}

const char* CFJsonStringGet(CFJson* jObj)
{
    if(!jObj)
        return NULL;
    if(jObj->type == cJSON_String && jObj->valuestring)
        return jObj->valuestring;
     return NULL;
}

CFJson* CFJsonIntNew(int num)
{
    return cJSON_CreateNumber((double)num);
}

CFJson* CFJsonInt64New(long long num)
{
    return cJSON_CreateNumber((double)num);
}

int CFJsonIntGet(CFJson* jObj, int* value)
{
    if(!jObj)
        return -1;
    if(jObj->type == cJSON_Number){
        *value = jObj->valueint;
        return 0;
    }
    return -1;
}

CFJson* CFJsonDoubleNew(double num)
{
    return cJSON_CreateNumber(num);
}

int CFJsonDoubleGet(CFJson* jObj, double* value)
{
    if(!jObj)
        return -1;
    if(jObj->type == cJSON_Number){
        *value = jObj->valuedouble;
        return 0;
    }
    return -1;
}

CFJson* CFJsonBoolNew(BOOL bl)
{
    if(bl!=TRUE && bl!=FALSE)
        return NULL;
    return cJSON_CreateBool(bl);
}

int CFJsonBoolGet(CFJson* jObj, BOOL* bl)
{
    if(!jObj)
        return -1;
    if(jObj->type == cJSON_False){
        *bl = FALSE;
        return 0;
    }else if(jObj->type == cJSON_True){
        *bl = TRUE;
        return 0;
    }
    return -1;    
}

const char* CFJsonObjectGetString(CFJson* jObj, const char* key)
{
    CFJson* obj;

    if(!jObj)
        return NULL;
    if((obj=CFJsonObjectGet(jObj, key)))
        return CFJsonStringGet(obj);
    return NULL;
}

int CFJsonObjectGetInt(CFJson* jObj, const char* key, int* value)
{
    CFJson* obj;

    if(!jObj)
        return -1;
    if((obj=CFJsonObjectGet(jObj, key)))
        return CFJsonIntGet(obj, value);
    return -1;
}

int CFJsonObjectGetDouble(CFJson* jObj, const char* key, double* value)
{
    CFJson* obj;
    
    if(!jObj)
        return -1;
    if((obj=CFJsonObjectGet(jObj, key)))
        return CFJsonDoubleGet(obj, value);
    return -1;
}

int CFJsonObjectGetBool(CFJson* jObj, const char* key, BOOL* value)
{
    CFJson* obj;
    
    if(!jObj)
        return -1;
    if((obj=CFJsonObjectGet(jObj, key)))
        return CFJsonBoolGet(obj, value);
    return -1;    
}

CFJson* CFJsonArrayNew()
{
    return cJSON_CreateArray();
}

int CFJsonArrayAdd(CFJson* array, CFJson* obj)
{
    if(!array || !obj)
        return -1;
    cJSON_AddItemToArray(array, obj);
    return 0;
}

int CFJsonArrayLen(CFJson* jObj)
{
    if(!jObj)
        return -1;
    if(jObj->type != cJSON_Array)
        return -1;
    return cJSON_GetArraySize(jObj);
}

CFJson* CFJsonArrayGet(CFJson* jObj, int idx)
{
    int i=0;

    if(!jObj)
        return NULL;
    CFJsonForeach(jObj, tmpObj){
        if(i==idx)
            return (tmpObj);
    }
    return NULL;
}

const char* CFJsonArrayGetString(CFJson* jObj, int idx)
{
    int i=0;
    
    if(!jObj)
        return NULL;
    if(jObj->type == cJSON_Array){
        CFJsonForeach(jObj, tmpObj){
            if(i==idx)
                return CFJsonStringGet(tmpObj);
        }
    }
    return NULL;
}

int CFJsonArrayGetInt(CFJson* jObj, int idx, int* value)
{
    int i=0;
    
    if(!jObj)
        return -1;
    if(jObj->type == cJSON_Array){
        CFJsonForeach(jObj, tmpObj){
            if(i==idx)
                return CFJsonIntGet(tmpObj, value);
        }
    }
    return -1;
}

int CFJsonArrayGetDouble(CFJson* jObj, int idx, double* value)
{
    int i=0;
    
    if(!jObj)
        return -1;
    if(jObj->type == cJSON_Array){
        CFJsonForeach(jObj, tmpObj){
            if(i==idx)
                return CFJsonDoubleGet(tmpObj, value);
        }
    }
    return -1;
}

char* CFJsonNewCStr(CFJson* jObj)
{
    if(!jObj)
        return NULL;
    return cJSON_Print(jObj);
}

int CFJsonGetString(CFJson* jObj, CFString* str)
{
    if(!jObj || !str)
        return -1;
    char* cStr;
    cStr = cJSON_Print(jObj);
    if(!cStr){
        return -1;
    }
    CFStringSafeCp(str, "");
    CFStringSafeCp(str, cStr);
    CFFree(cStr);
    return 0;
}

int CFJsonGetUnformatedString(CFJson* jObj, CFString* str)
{
    if(!jObj || !str)
        return -1;
    char* cStr;
    cStr = cJSON_PrintUnformatted(jObj);
    if(!cStr){
        return -1;
    }
    CFStringSafeCp(str, "");
    CFStringSafeCp(str, cStr);
    CFFree(cStr);
    return 0;
}

